//
//  main.cpp
//  BigNumber
//
//  Created by chenyh on 2021/2/19.
//

#include <iostream>
#include "BigNumber.hpp"
void add(BigNumber a,BigNumber b);
/**
 【例 4-4】 在进行科学计算中，很多时候会遇到值很大的数，这些数已经超出了任何
 计算及内置数据类型的表示范围，这样的数被称为大数。请设计一 个程序实现大数加法，大数位数在 15 位以上。
 
 【分析】这道题我们需要明白数值的表示都是通过各个位置上 的数字和所在位的权值来表示的。在这里，可以考虑利用数组来 存储数各位的数字，然后在两个数组之间模拟加法运算，如图 4-5 所示。
 采用上面这种形式存储的数在编译器的认知范围内只是一个数组，而并不是一个数， 所以常用的加、减、乘和除运算对这样的数据就是无效的，因此我们需要利用数组的一些 性质来重新定义四则运算。假设规定每个数组元素保存一个 4 位数，我们定义表示大数的 类如下:
 a[0]  a[1] a[2] a[3]
 1234  5678 2234 5678
 b[0]  b[1] b[2] b[3]
 1234  5678 2234 5678
 c[0]  c[1] c[2] c[3]
 ?      ?    ?    ?
 */
int main(int argc, const char * argv[]) {
    string a1,b1;
    cout<<"输入需要计算的数字"<<endl;
    cin>>a1>>b1;
    BigNumber a(a1);
    BigNumber b(b1);
    //测试加法
    cout<<"a+b的结果为："<<endl;
    add(a, b);
    return 0;
}
/*******************************大数加法运算****************************************/
/**
 加法运算是要求低位对齐，并且从低位开始运算，需要注意的是有进位的情况。我们 可以这样来处理:由于每个数组元素只存储最多4位的无符号整数，如果数组a[i]+b[i]=c[i] 时有进位，则必然是 a[i]+b[i]≥10000，那么 c[i1]的值加 1，c[i]的值应该减去 10000。这 符合四则运算加法的进位原则:高位加 1，低位减去进制权值。其实在这里，我们的进位 权值为 10000，每一个数组元素满 10000 向高位进 1。
 */
void add(BigNumber a,BigNumber b)
{
    //将位数较多的数赋值给maxNumber
    BigNumber maxNumber = a.getArraySize() >= b.getArraySize() ? a:b;
    //将位数较小的数赋值给minNumber
    BigNumber minNumber = a.getArraySize() < b.getArraySize() ? a : b;
    BigNumber c(maxNumber.getArraySize()); //以较多的位数创建大数C
    int* dataMax = maxNumber.getData();
    int* dataMin = minNumber.getData();
    int* dataC = c.getData();
    int i,j;
    int carray=0;
    //获取大数的数值数组
    //定义进位值，初始化为 0
    for (i=maxNumber.getArraySize()-1,j=i-(maxNumber.getArraySize()-minNumber.getArraySize());i>=0&&j>=0;i--,j--)
    {
        dataC[i] = dataMax[i] + dataMin[j] + carray;
        if (dataC[i] < 10000) {
            carray = 0;
        }else {
            carray = 1;//否则carrry为1.表示进一位
            dataC[i] = dataC[i] - 10000;// 进位后相应位的值减去权值
        }
    }
    while (i>=0) {
        dataC[i] = dataMax[i]+carray;
        if (dataC[i] < 10000) {
            carray=0;
        }else {
            carray = 1;
            dataC[i] = dataC[i] - 10000;
        }
        i--;
    }
  //判断最高位是否有进位，并作出相应处理
    if (carray == 1) {
        int *result = new int(c.getArraySize()+1);
        //如果最高位有进位，则重新创建一个数组
        result[0] = 1;  //进位后最高位为1
        dataC[0] = dataC[0] - 10000;//原最高位变成次高位，值减去权值
        for (int k = 1; k<c.getArraySize()+1; k++) {
            //将老数组中的剩余位的值赋值给新数组
            result[k] = dataC[k-1];
        }
        for (int i = 0; i<c.getArraySize()+1; i++) {
            if (i > 0 && result[i]<1000) {
                std::cout<<'0'<<result[i];//用0站位
            }else
                std::cout<<result[i];
        }
    }else {
        for (int i = 0;i<c.getArraySize();i++)
        {
                  if(i>0 && dataC[i]<1000)
                      std::cout<<'0'<<dataC[i];
                  else
                      std::cout<<dataC[i];
        }
    }
    
}
